/* eslint-disable vue/no-mutating-props */
/* eslint-disable vue/no-mutating-props */
/* eslint-disable no-use-before-define */
import { defineComponent, ref, watch, onMounted, withModifiers, SetupContext } from 'vue';
import { Color } from '../class/color.class';
import './scss/sv-panel.scss';
import { SvPanelProps, svPanelProps } from './props/sv-panel.props';

export default defineComponent({
    name: 'SvPanel',
    props: svPanelProps,
    emits: ['update:color'] as string[] | undefined,
    setup(props: SvPanelProps, context: SetupContext) {
        const cursor = ref<HTMLDivElement | null>(null);
        const elementRef = ref<HTMLDivElement | null>(null);
        const randomId = ref(props.randomId);
        const allowColorNull = ref(props.allowColorNull);
        // const hueRef = ref(props.hue);
        function backgroundColor() {
            return props.hue ? props.hue.toRgbaString() : '#3f51b5';
        }

        class clickValue {
            x = 0;

            y = 0;

            height = 0;

            width = 0;
        }
        function changePointerPosition(x: number, y: number): void {
            x = Math.max(0, Math.min(x, 100));
            y = Math.max(0, Math.min(y, 100));
            if (cursor.value) {
                cursor.value.style?.setProperty('top', `${100 - y}%`);
                cursor.value.style?.setProperty('left', `${x}%`);
            }
        }
        /** 修改禁止点击状态 */
        function changeBorderAndButtonStates() {
            // 选择颜色后，取消「确定」按钮的禁用状态
            const isCommitBtnDisabled = document.getElementById(`farris-color-picker-plus-sure-${randomId.value}`) as HTMLElement;
            isCommitBtnDisabled.className = 'btn btn-secondary';
            // 选择颜色后，取消输入框的红色警示状态
            const isCommitBtnNull = document.getElementById(`farris-color-picker-plus-input-${randomId.value}`) as HTMLElement;
            isCommitBtnNull.style.borderColor = '#dcdfe6';
        }
        function movePointer({ x, y, height, width }: clickValue): void {
            const saturation = (x * 100) / width;
            const bright = -((y * 100) / height) + 100;
            changePointerPosition(saturation, bright);

            const curColor = props.color == null || undefined ? 'transparent' : (props.color as any);
            const tmpColor = Color.from(curColor);

            changeBorderAndButtonStates();

            if (tmpColor != null) {
                const hsva = props.hue.getHsva();
                const color = tmpColor.getHsva();
                const newColor = new Color().setHsva(hsva.hue, saturation, bright, color.alpha);
                context.emit('update:color', newColor);
            }
            // 若颜色值为空，但允许为空
            if (!tmpColor && allowColorNull.value) {
                context.emit('update:color', null);
            }
        }
        function calculateCoordinates(event: MouseEvent | TouchEvent): void {
            if (elementRef.value) {
                const { width: elWidth, height: elHeight, top: elTop, left: elLeft } = elementRef.value.getBoundingClientRect();
                const { pageX, pageY } = 'touches' in event ? event.touches[0] : event;

                const x = Math.max(0, Math.min(pageX - (elLeft + window.pageXOffset), elWidth));
                const y = Math.max(0, Math.min(pageY - (elTop + window.pageYOffset), elHeight));

                movePointer({ x, y, height: elHeight, width: elWidth });
            }
        }

        onMounted(() => {
            const hsva = props.color.getHsva();
            changePointerPosition(hsva.saturation, hsva.value);
        });

        watch(
            () => props.color,
            (newValue) => {
                const hsva = newValue.getHsva();
            }
        );
        watch(
            () => props.color,
            (newValue) => {
                const hsva = newValue.getHsva();
                changePointerPosition(hsva.saturation, hsva.value);
            }
        );
        return () => (
            <div
                class="f-sv-panel-component"
                ref={elementRef}
                style={{ backgroundColor: backgroundColor() }}
                onMousedown={withModifiers((payload: MouseEvent) => calculateCoordinates(payload), ['prevent'])}
                onTouchstart={withModifiers((payload: TouchEvent) => calculateCoordinates(payload), ['prevent'])}>
                <div class="color-svpanel__white"></div>
                <div class="color-svpanel__black"></div>
                <div class="color-svpanel__cursor" ref={cursor}>
                    <div></div>
                </div>
            </div>
        );
    }
});
